package com.mybatis.jpa.mapper;

import java.util.List;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mybatis.jpa.annotation.NestedSelect;
import org.apache.ibatis.annotations.Param;

import com.mybatis.jpa.annotation.StatementDefinition;

/**
 * 规范通用Mapper方法签名</br>
 *
 * 子类Mapper通过继承此接口获取方法签名,并使用{@MapperDefinition}注解标记Mapper.</br>
 * 使用{@StatementDefinition}注解标记的方法,将被解析并注入到Mybatis Statement</br>
 *
 * about deference with insert(){@link #insert(Object)} and insertSelective()
 * {@link #insertSelective(Object)}</br>
 * 方法的区别在于null值的处理,假设column_1在数据库设置了默认值,而参数中的field_1为null值,则insert
 * 在数据库写入null,而insertSelective写入数据库默认值.
 *
 * @attation 并非要继承此接口才能使用mybatis-jpa,事实上它只是定义了公共的Mapper方法签名,便于代码风格的统一
 *
 *
 * @author svili
 * @data 2017年5月8日
 *
 * @param <T>持久化Entity类型
 */
public interface MybatisBaseMapper<T> extends BaseMapper<T>{

	/**
	 * 做判空处理的insert
	 * @param entity do
	 * @return 受影响的行数
	 */
	@StatementDefinition
	int insertSelective(T entity);

	/**
	 * 插入
	 * @param entity
	 * @return int 受影响的行数
	 * @since  1.0.0
	*/
	@StatementDefinition
	int insertJpa(T entity);

	/**
	 * 批量插入
	 * @param list 需要插入的集合
	 * @return 受影响的行数
	 * @since  1.0.0
	*/
	@StatementDefinition
	int batchInsert(@Param("list")List<T> list);

	/**
     * 批量插入.
     *
     * @param list 需要插入的集合
     * @param flag 分表标志
     * @return 受影响的行数
     * @since 1.0.0
     */
    @StatementDefinition
    int batchInsertCatTable(@Param("list")List<T> list,@Param("flag")String flag);

	/**
	 * 根据id删除数据
	 * @param primaryValue id
	 * @return 受影响行数
	 * @since  1.0.0
	*/
	@StatementDefinition
	int deleteByIdJpa(Object primaryValue);

	/**
     * 根据id删除数据
     * @param primaryValue id
     * @param flag 分表标志
     * @return 受影响行数
     * @since  1.0.0
    */
    @StatementDefinition
    int deleteByIdCatTable(@Param("param")Object primaryValue,@Param("flag")String flag);

	/**
	 * 根据id更新
	 * @param entity 待更新数据
	 * @return   受影响行数
	 * @since  1.0.0
	*/
	@StatementDefinition
	int updateByIdJpa(T entity);

	/**
	 * 根据id跟新 -- 判空
	 * @param entity 待更新数据
     * @return   受影响行数
	 * @since  1.0.0
	*/
	@StatementDefinition
	int updateSelectiveById( T entity);


	/**
	 * 高级更新
	 * @param entity 更新的值
	 * @param baseWhere 基础的where条件
	 * @param sql 扩展sql
	 * @return 受影响行数
	 */
	@StatementDefinition
	int updateByAdvance(@Param("entity") T entity,@Param("baseWhere")T baseWhere,@Param("extSql") String sql);

	/**
	 * 批量根据id更新-null字段设置不进去
	 * @param list 集合
	 * @return 受影响行数
	 */
	@StatementDefinition
	int batchUpdateById(@Param("list")List<T> list);

	/**
	 * 批量根据id更新--可以设置null
	 * @param list 集合
	 * @return 受影响行数
	 */
	@StatementDefinition
	int batchUpdateIncludeNullById(@Param("list")List<T> list);

	/**
	 * 根据id、查询
	 * @param primaryValue id
	 * @return   model
	 * @since  1.0.0
	*/
	@StatementDefinition
	T selectByIdJpa(Object primaryValue);


	/**
	 *  级联查询 支持one2one one2x
	 * @param entity  过滤条件
	 * @param pageStart 分页开始
	 * @param pageSize 分页行数
	 * @return 级联查询结果
	 */
	@NestedSelect
	@StatementDefinition
	List<T> selectNested(@Param("entity")T entity,@Param("pageStart")long pageStart,@Param("pageSize")long pageSize);

	/**
	 *  级联查询 支持one2one one2x
	 * @param entity  过滤条件
	 * @param pageStart 分页开始
	 * @param pageSize 分页行数
	 * @param orderBy 排序参数
	 * @return 级联查询结果
	 */
	@NestedSelect
	@StatementDefinition
	List<T> selectNestedForOrder(@Param("entity")T entity,@Param("pageStart")long pageStart,@Param("pageSize")long pageSize,@Param("orderBy")String orderBy);

	/**
     * 根据id、查询
     * @param primaryValue id
     * @return   model
     * @since  1.0.0
    */
    @StatementDefinition
    T selectByIdCatTable(@Param("param")Object primaryValue,@Param("flag")String flag);


	/**
	 * 根据分页参数返回结果
	 * 如果不需要分页 pageStart或者pageSize传-1即可
	 * @param entity 用来做过滤的参数
	 * @param pageStart 开始number
	 * @param pageSize 一页多少行数据
	 * @return 符合条件的数据
	 */
	@StatementDefinition
	List<T> selectPageJpa(@Param("entity")T entity,@Param("pageStart")long pageStart,@Param("pageSize")long pageSize);

	/**
	 * 根据分页参数返回结果
	 * 如果不需要分页 pageStart或者pageSize传-1即可
	 * @param entity 用来做过滤的参数
	 * @param pageStart 开始number
	 * @param pageSize 一页多少行数据
	 * @param orderBy  排序字段
	 * @return 符合条件的数据
	 */
	@StatementDefinition
	List<T> selectPageForOrder(@Param("entity")T entity,@Param("pageStart")long pageStart,@Param("pageSize")long pageSize,@Param("orderBy")String orderBy);


	/**
	 * 根据参数查询总数
	 * 如果不需要分页 pageStart或者pageSize传0即可
	 * @param entity 用来做过滤的参数
	 * @return 符合条件的数据条数
	 */
	@StatementDefinition
	long selectCountJpa(T entity);

	/**
     * 根据条件查询bean对象
     * @param entity 用来做过滤的参数
     * @return 符合条件的数据
     */
    @StatementDefinition
    T selectBean(T entity);


	/**
	 * 高级查询
	 * @param baseWhere 基础where
	 * @param extWhereSql where
	 * @param pageStart 开始
	 * @param pageSize 每页多少条
	 * @param orderBy 排序
	 * @return 符合条件的数据
	 */
	@StatementDefinition
	List<T> selectAdvance(@Param("entity")T baseWhere,@Param("extWhereSql") String extWhereSql,@Param("pageStart")long pageStart,@Param("pageSize")long pageSize,@Param("orderBy")String orderBy);


	/**
	 * 高级查询
	 * @param baseWhere 基础where
	 * @param extWhereSql where
	 * @return 符合条件的数据
	 */
	@StatementDefinition
	long selectCountAdvance(@Param("entity")T baseWhere,@Param("extWhereSql") String extWhereSql);

	/**
	 * select(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @return 查询所有
	 * @since  1.0.0
	*/
	@StatementDefinition
	List<T> select();

	/**
	 * 给定参数进行删除 操作
	 * @param entity 参数
	 * @return 影响行数
	 */
	@StatementDefinition
	int deleteBean(T entity);

	/**
	 * 根据id集合查询
	 * @param ids ids
	 * @return 对应的PO
	 */
	@StatementDefinition
	List<T> selectByIds(@Param("ids")List<? extends  Object> ids);
}
